/*
 * Copyright 2002-2024 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.support;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeansException;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.support.ResourceEditorRegistrar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ApplicationStartupAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.expression.StandardBeanExpressionResolver;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
import org.springframework.core.NativeDetector;
import org.springframework.core.ResolvableType;
import org.springframework.core.SpringProperties;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

/**
 * Abstract implementation of the {@link org.springframework.context.ApplicationContext}
 * interface. Doesn't mandate the type of storage used for configuration; simply
 * implements common context functionality. Uses the Template Method design pattern,
 * requiring concrete subclasses to implement abstract methods.
 *
 * <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed
 * to detect special beans defined in its internal bean factory:
 * Therefore, this class automatically registers
 * {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},
 * {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors},
 * and {@link org.springframework.context.ApplicationListener ApplicationListeners}
 * which are defined as beans in the context.
 *
 * <p>A {@link org.springframework.context.MessageSource} may also be supplied
 * as a bean in the context, with the name "messageSource"; otherwise, message
 * resolution is delegated to the parent context. Furthermore, a multicaster
 * for application events can be supplied as an "applicationEventMulticaster" bean
 * of type {@link org.springframework.context.event.ApplicationEventMulticaster}
 * in the context; otherwise, a default multicaster of type
 * {@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.
 *
 * <p>Implements resource loading by extending
 * {@link org.springframework.core.io.DefaultResourceLoader}.
 * Consequently treats non-URL resource paths as class path resources
 * (supporting full class path resource names that include the package path,
 * e.g. "mypackage/myresource.dat"), unless the {@link #getResourceByPath}
 * method is overridden in a subclass.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Stephane Nicoll
 * @author Sam Brannen
 * @author Sebastien Deleuze
 * @author Brian Clozel
 * @since January 21, 2001
 * @see #refreshBeanFactory
 * @see #getBeanFactory
 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
 * @see org.springframework.beans.factory.config.BeanPostProcessor
 * @see org.springframework.context.event.ApplicationEventMulticaster
 * @see org.springframework.context.ApplicationListener
 * @see org.springframework.context.MessageSource
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {

	/**
	 * The name of the {@link MessageSource} bean in the context.
	 * If none is supplied, message resolution is delegated to the parent.
	 * @see org.springframework.context.MessageSource
	 * @see org.springframework.context.support.ResourceBundleMessageSource
	 * @see org.springframework.context.support.ReloadableResourceBundleMessageSource
	 * @see #getMessage(MessageSourceResolvable, Locale)
	 */
	public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

	/**
	 * The name of the {@link ApplicationEventMulticaster} bean in the context.
	 * If none is supplied, a {@link SimpleApplicationEventMulticaster} is used.
	 * @see org.springframework.context.event.ApplicationEventMulticaster
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 * @see #publishEvent(ApplicationEvent)
	 * @see #addApplicationListener(ApplicationListener)
	 */
	public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";

	/**
	 * The name of the {@link LifecycleProcessor} bean in the context.
	 * If none is supplied, a {@link DefaultLifecycleProcessor} is used.
	 * @since 3.0
	 * @see org.springframework.context.LifecycleProcessor
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 * @see #start()
	 * @see #stop()
	 */
	public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";


	/**
	 * Boolean flag controlled by a {@code spring.spel.ignore} system property that
	 * instructs Spring to ignore SpEL, i.e. to not initialize the SpEL infrastructure.
	 * <p>The default is "false".
	 */
	private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");


	static {
		// 优先加载上下文关闭事件来防止奇怪的类加载问题在应用程序关闭的时候
		// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
		// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
		ContextClosedEvent.class.getName();
	}


	/** Logger used by this class. Available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	//创建上下文的唯一标识
	/** Unique id for this context, if any. */
	private String id = ObjectUtils.identityToString(this);

	/** Display name. */
	private String displayName = ObjectUtils.identityToString(this);

	/** Parent context. */
	@Nullable
	private ApplicationContext parent;

	/** Environment used by this context. */
	@Nullable
	private ConfigurableEnvironment environment;

	/** BeanFactoryPostProcessors to apply on refresh. */
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

	/** System time in milliseconds when this context started. */
	private long startupDate;

	/** Flag that indicates whether this context is currently active. */
	private final AtomicBoolean active = new AtomicBoolean();

	/** Flag that indicates whether this context has been closed already. */
	private final AtomicBoolean closed = new AtomicBoolean();

	// ====== 同步监视器的"刷新"和"销毁"
	/** Synchronization monitor for "refresh" and "close". */
	private final Object startupShutdownMonitor = new Object();

	/** Reference to the JVM shutdown hook, if registered. */
	@Nullable
	private Thread shutdownHook;

	/** ResourcePatternResolver used by this context. */
	private final ResourcePatternResolver resourcePatternResolver;

	/** LifecycleProcessor for managing the lifecycle of beans within this context. */
	@Nullable
	private LifecycleProcessor lifecycleProcessor;

	/** MessageSource we delegate our implementation of this interface to. */
	@Nullable
	private MessageSource messageSource;

	/** Helper class used in event publishing. */
	@Nullable
	private ApplicationEventMulticaster applicationEventMulticaster; // ====== 多播器

	/** Application startup metrics. **/
	private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;

	//====== 静态指定的侦听器
	//用来存放applicationListeners的集合对象
	/** Statically specified listeners. */
	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

	/** Local listeners registered before refresh. */
	@Nullable
	private Set<ApplicationListener<?>> earlyApplicationListeners;

	/** ApplicationEvents published before the multicaster setup. */
	@Nullable
	private Set<ApplicationEvent> earlyApplicationEvents;


	/**
	 * Create a new AbstractApplicationContext with no parent.
	 */
	//创建一个无父类的AbstractApplicationContext对象
	public AbstractApplicationContext() {
		// ====== 找到 ! 解析器
		// 创建资源模式处理器
		this.resourcePatternResolver = getResourcePatternResolver(); // →
		// ====== 那classloader呢？提示：到当前类的父类里找无参构造函数，去翻一翻！
	}

	/**
	 * Create a new AbstractApplicationContext with the given parent context.
	 * @param parent the parent context
	 */
	public AbstractApplicationContext(@Nullable ApplicationContext parent) {
		// ====== 有门道了！进去
		this(); // -> 5
		// ====== 设置父容器，此处为空 , 不管他
		setParent(parent);
	}


	//---------------------------------------------------------------------
	// Implementation of ApplicationContext interface
	//---------------------------------------------------------------------

	/**
	 * Set the unique id of this application context.
	 * <p>Default is the object id of the context instance, or the name
	 * of the context bean if the context is itself defined as a bean.
	 * @param id the unique id of the context
	 */
	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public String getApplicationName() {
		return "";
	}

	/**
	 * Set a friendly name for this context.
	 * Typically done during initialization of concrete context implementations.
	 * <p>Default is the object id of the context instance.
	 */
	public void setDisplayName(String displayName) {
		Assert.hasLength(displayName, "Display name must not be empty");
		this.displayName = displayName;
	}

	/**
	 * Return a friendly name for this context.
	 * @return a display name for this context (never {@code null})
	 */
	@Override
	public String getDisplayName() {
		return this.displayName;
	}

	/**
	 * Return the parent context, or {@code null} if there is no parent
	 * (that is, this context is the root of the context hierarchy).
	 */
	@Override
	@Nullable
	public ApplicationContext getParent() {
		return this.parent;
	}

	/**
	 * Set the {@code Environment} for this application context.
	 * <p>Default value is determined by {@link #createEnvironment()}. Replacing the
	 * default with this method is one option but configuration through {@link
	 * #getEnvironment()} should also be considered. In either case, such modifications
	 * should be performed <em>before</em> {@link #refresh()}.
	 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
	 */
	@Override
	public void setEnvironment(ConfigurableEnvironment environment) {
		this.environment = environment;
	}

	/**
	 * Return the {@code Environment} for this application context in configurable
	 * form, allowing for further customization.
	 * <p>If none specified, a default environment will be initialized via
	 * {@link #createEnvironment()}.
	 */
	@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			// ====== 开始创建环境
			this.environment = createEnvironment();
		}
		return this.environment;
	}

	/**
	 * Create and return a new {@link StandardEnvironment}.
	 * <p>Subclasses may override this method in order to supply
	 * a custom {@link ConfigurableEnvironment} implementation.
	 */
	protected ConfigurableEnvironment createEnvironment() {
		// ====== 返回一个标准的环境， 如果没有构造器，继续查看父容器
		// ###### 会先执行StandardEnvironment的父类的无参构造方法，会将操作系统与JVM环境变量添加到Environment中
		return new StandardEnvironment();
	}

	/**
	 * Return this context's internal bean factory as AutowireCapableBeanFactory,
	 * if already available.
	 * @see #getBeanFactory()
	 */
	@Override
	public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
		return getBeanFactory();
	}

	/**
	 * Return the timestamp (ms) when this context was first loaded.
	 */
	@Override
	public long getStartupDate() {
		return this.startupDate;
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be application-specific or a
	 * standard framework event)
	 */
	//将给定事件发布到所有监听器
	@Override
	public void publishEvent(ApplicationEvent event) {
		publishEvent(event, null);
	}

	/**
	 * Publish the given event to all listeners.
	 * <p>Note: Listeners get initialized after the MessageSource, to be able
	 * to access it within listener implementations. Thus, MessageSource
	 * implementations cannot publish events.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 */
	//将给定事件发布到所有监听器
	@Override
	public void publishEvent(Object event) {
		publishEvent(event, null);
	}

	/**
	 * Publish the given event to all listeners.
	 * @param event the event to publish (may be an {@link ApplicationEvent}
	 * or a payload object to be turned into a {@link PayloadApplicationEvent})
	 * @param eventType the resolved event type, if known
	 * @since 4.2
	 */
	//将给定事件发布到所有监听器
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		// 如果event为null，抛出异常
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		// 装饰事件作为一个应用事件，如果有必要
		ApplicationEvent applicationEvent;
		// 如果event是ApplicationEvent的实例
		if (event instanceof ApplicationEvent) {
			// 将event强转为ApplicationEvent对象
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			// PayloadApplicationEvent：携带任意有效负载的ApplicationEvent。
			// 创建一个新的PayloadApplicationEvent
			applicationEvent = new PayloadApplicationEvent<>(this, event);
			// 如果eventType为 null
			if (eventType == null) {
				// 将applicationEvent转换为PayloadApplicationEvent对象，引用其ResolvableType对象
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		// 如果可能的话，现在就进行组播——或者在组播初始化后延迟
		// earlyApplicationEvents：在多播程序设置之前发布的ApplicationEvent
		// 如果earlyApplicationEvents不为 null，这种情况只在上下文的多播器还没有初始化的情况下才会成立，会将applicationEvent
		// 添加到earlyApplicationEvents保存起来，待多博器初始化后才继续进行多播到适当的监听器
		if (this.earlyApplicationEvents != null) {
			//将applicationEvent添加到 earlyApplicationEvents
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			// ====== 断点，就在这里！底层执行的也是这个事件发布
			// 多播applicationEvent到适当的监听器
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		// 通过父上下文发布事件
		// 如果parent不为null
		if (this.parent != null) {
			// 如果parent是AbstractApplicationContext的实例
			if (this.parent instanceof AbstractApplicationContext) {
				// 将event多播到所有适合的监听器。如果event不是ApplicationEvent实例，会将其封装成PayloadApplicationEvent对象再进行多播
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				// 通知与event事件应用程序注册的所有匹配的监听器
				this.parent.publishEvent(event);
			}
		}
	}

	/**
	 * Return the internal ApplicationEventMulticaster used by the context.
	 * @return the internal ApplicationEventMulticaster (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
		if (this.applicationEventMulticaster == null) {
			throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
					"call 'refresh' before multicasting events via the context: " + this);
		}
		return this.applicationEventMulticaster;
	}

	@Override
	public void setApplicationStartup(ApplicationStartup applicationStartup) {
		Assert.notNull(applicationStartup, "ApplicationStartup must not be null");
		this.applicationStartup = applicationStartup;
	}

	@Override
	public ApplicationStartup getApplicationStartup() {
		return this.applicationStartup;
	}

	/**
	 * Return the internal LifecycleProcessor used by the context.
	 * @return the internal LifecycleProcessor (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
		if (this.lifecycleProcessor == null) {
			throw new IllegalStateException("LifecycleProcessor not initialized - " +
					"call 'refresh' before invoking lifecycle methods via the context: " + this);
		}
		return this.lifecycleProcessor;
	}

	/**
	 * Return the ResourcePatternResolver to use for resolving location patterns
	 * into Resource instances. Default is a
	 * {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver},
	 * supporting Ant-style location patterns.
	 * <p>Can be overridden in subclasses, for extended resolution strategies,
	 * for example in a web environment.
	 * <p><b>Do not call this when needing to resolve a location pattern.</b>
	 * Call the context's {@code getResources} method instead, which
	 * will delegate to the ResourcePatternResolver.
	 * @return the ResourcePatternResolver for this context
	 * @see #getResources
	 * @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
	 */
	// ====== 仅仅返回一个路径匹配资源模式解析器
	protected ResourcePatternResolver getResourcePatternResolver() {
		// 创建一个资源模式解析器(其实就是用来解析xml配置文件)
		return new PathMatchingResourcePatternResolver(this);
	}


	//---------------------------------------------------------------------
	// Implementation of ConfigurableApplicationContext interface
	//---------------------------------------------------------------------

	/**
	 * Set the parent of this application context.
	 * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is
	 * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with
	 * this (child) application context environment if the parent is non-{@code null} and
	 * its environment is an instance of {@link ConfigurableEnvironment}.
	 * @see ConfigurableEnvironment#merge(ConfigurableEnvironment)
	 */
	// ====== 设置父容器，此处为空
	@Override
	public void setParent(@Nullable ApplicationContext parent) {
		this.parent = parent;
		if (parent != null) {
			Environment parentEnvironment = parent.getEnvironment();
			if (parentEnvironment instanceof ConfigurableEnvironment) {
				getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
			}
		}
	}

	@Override
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}

	/**
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

	@Override
	public void addApplicationListener(ApplicationListener<?> listener) {
		Assert.notNull(listener, "ApplicationListener must not be null");
		if (this.applicationEventMulticaster != null) {
			this.applicationEventMulticaster.addApplicationListener(listener);
		}
		this.applicationListeners.add(listener);
	}

	/**
	 * Return the list of statically specified ApplicationListeners.
	 */
	public Collection<ApplicationListener<?>> getApplicationListeners() {
		return this.applicationListeners;
	}

	// ====== 模板方法（抽象类下定义refresh模板），核心方法
	// ====== 断点查看
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		// ====== synchronized块锁（monitorenter --monitorexit）
		// ====== 不然 refresh() 还没结束，又来个启动或销毁容器的操作
		// ====== startupShutdownMonitor就是个空对象，锁
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// ###### 1.初始化前的预处理
			// ====== 1、[准备刷新],设置了几个变量,也是准备工作
			/** 
			 * 前戏，做容器刷新前的准备工作
			 * 1、设置容器的启动时间
			 * 2、设置活跃状态为true
			 * 3、设置关闭状态为false
			 * 4、获取Environment对象，并加载当前系统的属性值到Environment对象中
			 * 5、准备监听器和事件的集合对象，默认为空的集合
			 */
			// 准备刷新的上下文环境
			// Prepare this context for refreshing.
			prepareRefresh(); //===>

			// ###### 2.获取BeanFactory,加载所有Bean的定义信息(未实例化)
			// ====== 2、【获得新的bean工厂】关键步骤，重点！
			/** ======
			 	2.1、关闭旧的 BeanFactory
			 	2.2、创建新的 BeanFactory（DefaluListbaleBeanFactory）
			 	2.3、解析xml/加载 Bean 定义、注册 Bean定义到beanFactory(不初始化)
			 	2.4、返回全新的工厂
			 */
			//  创建容器对象：DefaultListableBeanFactory
			//  加载xml配置文件的属性值到当前工厂中，最重要的就是BeanDefinition
			// ###### 这里会判断能否刷新，并且返回一个BeanFactory, 刷新不代表完全情况，主要是先执行Bean的销毁，然后重新生成一个BeanFactory，再在接下来的步骤中重新去扫描等等
			// 初始化BeanFactory，并进行XML文件读取
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //===>好戏开始

			// ###### 3.BeanFactory的预处理配置
			// ====== 3、【bean工厂前置操作】为BeanFactory配置容器特性
			// ====== 例如类加载器、表达式解析器、注册默认环境bean、后置管理器
			//  beanFactory的准备工作，对各种属性进行填充
			// ###### 准备BeanFactory
			// ###### 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
			// ###### 2. 添加三个BeanPostProcessor，注意是具体的BeanPostProcessor实例对象
			// ###### 3. 记录ignoreDependencyInterface
			// ###### 4. 记录ResolvableDependency
			// ###### 5. 添加三个单例Bean
			// 对BeanFactory进行各种功能填充
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory); // ===>

			try {
				// ###### 4. 准备BeanFactory完成后进行的后置处理
				// ====== 4、【bean工厂后置操作】此处为空方法，如果子类需要，自己去实现
				//  子类覆盖方法做额外的处理，此处我们自己一般不做任何扩展工作，但是可以查看web中的代码，是有具体实现的
				// ###### 子类来设置一下BeanFactory
				// 子类覆盖方法做额外的处理
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory); // ===> 空的！

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

				// ###### 5.执行BeanFactory创建后的后置处理器
				// ====== 5、【调用bean工厂后置处理器】,开始调用我们自己实现的接口
				// ====== 目标：
				// ====== 调用顺序一：先bean定义注册后置处理器
				// ====== 调用顺序二：后bean工厂后置处理器
				//  调用各种beanFactory处理器
				// ###### BeanFactory准备好了之后，执行BeanFactoryPostProcessor，开始对BeanFactory进行处理
				// ###### 默认情况下:
				// ###### 此时beanFactory的beanDefinitionMap中有6个BeanDefinition，5个基础BeanDefinition+AppConfig的BeanDefinition
				// ###### 而这6个中只有一个BeanFactoryPostProcessor：ConfigurationClassPostProcessor
				// ###### 这里会执行ConfigurationClassPostProcessor进行@Component的扫描，扫描得到BeanDefinition，并注册到beanFactory中
				// ###### 注意：扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor，那么这些BeanFactoryPostProcessor也得在这一步执行
				// 激活各种BeanFactory处理器
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);  // scanner.scan() // ===>  重头戏

				// ###### 6.注册Bean的后置处理器
				// ====== 6、【注册bean后置处理器】只是注册，但是还不会调用
				// ====== 逻辑：找出所有实现BeanPostProcessor接口的类,分类、排序、注册
				//  注册bean处理器，这里只是注册功能，真正调用的是getBean方法
				// ###### 将扫描到的BeanPostProcessors实例化并排序，并添加到BeanFactory的beanPostProcessors属性中去
				// 注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean时候
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);// ===>  关键点

				beanPostProcess.end();

				// ###### 7.初始化MessageSource
				// ====== 7、【初始化消息源】国际化问题i18n,参照https://nacos.io/
				//  为上下文初始化message源，即不同语言的消息体，国际化处理,在springmvc的时候通过国际化的代码重点讲
				// ###### 设置ApplicationContext的MessageSource，要么是用户设置的，要么是DelegatingMessageSource
				// 为上下文初始化Message源，即不同语言的消息体 ，国际化处理
				// Initialize message source for this context.
				initMessageSource();// ===> 就是往factory加了个single bean

				// ###### 8.初始化事件广播器
				// ====== 8、【初始化事件广播器】初始化自定义的事件监听多路广播器
				/** ======
				     如果需要发布事件，就调它的multicastEvent方法
				     把事件广播给listeners，其实就是起一个线程来处理，把Event扔给listener处理
				     (可以通过 SimpleApplicationEventMulticaster的代码来验证)
				 */
				//  初始化事件监听多路广播器
				// ###### 设置ApplicationContext的applicationEventMulticaster，要么是用户设置的，要么是SimpleApplicationEventMulticaster
				// 初始化应用消息广播器，并放入“applicationEventMulticaster”bean中
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();// ===> 同样，加了个bean

				// ###### 9.供子类扩展的模板方法onRefresh
				// ======  9、【刷新】这是个protected空方法，交给具体的子类来实现
				// ======  可以在这里初始化一些特殊的 Bean
				// ====== （在初始化 singleton beans 之前）
				//  留给子类来初始化其他的bean
				// ######  给子类的模板方法
				// 留给子类来初始化其它的Bean
				// Initialize other special beans in specific context subclasses.
				onRefresh(); // ===> 空的！一般没人管它

				// ###### 10.注册监听器
				// ======  10、【注册监听器】，监听器需要实现 ApplicationListener 接口
				// ======  也就是扫描这些实现了接口的类，给他放进广播器的列表中
				// ======  其实就是个观察者模式，广播器接到事件的调用时，去循环listeners列表，
				// ======  挨个调它们的onApplicationEvent方法，把event扔给它们。
				// 在所有注册的bean中查找listener bean,注册到消息广播器中
				// ###### 把定义的ApplicationListener的Bean对象，设置到ApplicationContext中去，并执行在此之前所发布的事件
				// 在所有注册的bean中查找Listener bean，注册到消息广播器中
				// Check for listener beans and register them.
				registerListeners(); // ====> 观察者模式

				// 至此,BeanFactory已创建并初始化完成

				// ###### 11.初始化所有剩下的单实例bean对象
				// ====== 11、 【结束bean工厂初始化操作】
				// ====== 1、初始化所有的 singleton beans,反射生成对象/填充
				// ====== 2、调用Bean的前置处理器和后置处理器
				// ====== 关键点：getBean方法里完成
				// 初始化剩下的单实例(非懒加载的)
				// 初始化剩下的单实例(非惰性的)
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory); // ===>关键点

				// ###### 12.完成容器的创建工作
				// ====== 12、结束refresh操作
				// ====== 发布事件与清除上下文环境
				//  完成刷新过程，通知生命周期处理器lifecycleProcessor刷新过程，同时发出ContextRefreshEvent通知别人
				// 完成刷新过程，通知生命周期处理器 lifecycleProcessor 刷新过程，同时发出ContextRefreshEvent通知别人
				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// ====== 销毁已创建的Bean、以免有些 bean 会一直占用资源
				// 为防止bean资源占用，在异常处理中，销毁已经在前面过程中生成的单例bean
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// ====== 取消refresh操作，重置容器的同步标识
				// 重置active标志
				// Reset 'active' flag.
				cancelRefresh(ex);

				// ====== 把异常往外抛
				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// ###### 13.清除缓存
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

	/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	/* ======
		1、记录启动时间/设置开始标志
		2、子类属性扩展
		3、校验xml配置文件
		4、初始化早期发布的应用程序事件对象（仅仅是创建setg对象）
	 */
	protected void prepareRefresh() {
		// 设置容器启动的时间
		// ###### 记录刷新动作执行的时间
		// ====== 1、设置3个属性的值，没啥可说的，一个时间，两个标记位
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
		// ###### 标记当前IOC容器已激活
		// 容器的关闭标志位
		// ====== AtomicBoolean 类型，当前context是否被关闭
		this.closed.set(false);
		// 容器的激活标志位
		// ====== AtomicBoolean 类型，当前context是否被激活
		// ====== refresh失败出现异常的时候，会再改成false，可以多次refresh尝试
		this.active.set(true);
		// 记录日志
		// ====== 打条日志，看控制台
		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}
		// 留给子类覆盖，初始化属性资源
		// ###### 初始化属性配置
		// ====== 2、protected，交给子类实现：在上下文环境中初始化属性源，非重点
		// ###### 比如子类可以把ServletContext中的参数对设置到Environment
		// 留给子类覆盖
		// Initialize any placeholder property sources in the context environment.
		initPropertySources(); //  ===>  默认情况下其实为空

		// 创建并获取环境对象，验证需要的属性文件是否都已经放入环境中
		// ###### 属性校验(通常无实际操作)
		// ====== 3、校验配置文件的属性，合法性， 否则终止加载流程
		// 验证需要的属性文件是否都已经放入环境中
		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// 判断刷新前的应用程序监听器集合是否为空，如果为空，则将监听器添加到此集合中
		// ###### 监听器的初始化(兼顾可以反复刷新的IOC容器)
		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// 如果不等于空，则清空集合元素对象
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// 创建刷新前的监听事件集合
		// ###### 初始化早期事件的集合
		// ====== 4、初始化一个set，用于记录应用程序事件
		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

	/**
	 * <p>Replace any stub property sources with actual instances.
	 * @see org.springframework.core.env.PropertySource.StubPropertySource
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
	 */
	protected void initPropertySources() {
		// 对于子类：默认情况下不执行任何操作
		// For subclasses: do nothing by default.
	}

	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	/* ======
		1、关闭旧的 BeanFactory
		2、创建新的 BeanFactory(DefaluListbaleBeanFactory)
		3、解析xml/加载 Bean 定义、注册 Bean定义到beanFactory(未初始化)
		4、返回全新的工厂
	*/
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//###### 刷新BeanFactory
		//======（c）关闭旧的 BeanFactory (如果有)，创建新的 BeanFactory，加载 Bean 定义、注册 Bean 等
		//初始化BeanFactory，并进行XML文件读取,并将得到的BeanFactory记录在当前实体的属性中
		refreshBeanFactory(); //  ===>  主方法，come on!
		//====== 返回刚刚通过解析创建的 BeanFactory
		//返回当前实体的beanFactory属性
		return getBeanFactory();
	}


	/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * @param beanFactory the BeanFactory to configure
	 */
	// ====== 目标：
	/* ======
		1、设置 BeanFactory 的类加载器 - 下一步就要初始化类了！
		2、设置 BeanFactory 的表达式解析器
		3、设置 BeanFactory 的属性编辑器
		4、智能注册
	*/
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// ###### 设置BeanFactory的类加载器、表达式解析器等
		// ====== 设置 BeanFactory 的类加载器 BeanFactory 需要加载类，也就需要类加载器
		// 设置beanFactory的classLoader为当前context的classLoader
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());

		// ###### Spring5.3中新增的功能，可以选择是否开启Spel功能，shouldIgnoreSpel默认为false，表示开启
		if (!shouldIgnoreSpel) {
			// ====== 设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
			// 设置beanFactory的表达式语言处理器，Spring3增加了表达式语言的支持
			// 默认可以使用#{bean.xxx}的形式来调用相关属性值。
			beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		}
		// ====== 设置属性注册解析器PropertyEditor
		// ###### 添加一个ResourceEditorRegistrar，注册一些级别的类型转化器
		// 为beanFactory增加了一个默认的propertyEditor，这个主要是对bean的属性等设置管理
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
		// ###### 配置一个可回调注入ApplicationContext的BeanPostProcessor
		// ====== 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理
		// ====== 从而在Aware接口实现类中的注入applicationContext
		// ====== 我们写的一堆xxxAware就是依靠这里才能得以生效。
		// ###### 组成一个BeanPostProcessor，用来处理EnvironmentAware、EmbeddedValueResolverAware等回调
		// 添加BeanPostProcessor,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入
		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 设置要忽略自动装配的接口，很多同学理解不了为什么此处要对这些接口进行忽略，原因非常简单，这些接口的实现是由容器通过set方法进行注入的，
		// 所以在使用autowire进行注入的时候需要将这些接口进行忽略
		// ====== 忽略依赖接口
		/* ======
			 skip：下面几行的意思就是，如果某个 bean 依赖于以下几个接口的实现类，在自动装配的时候忽略它们，
			 Spring会通过其他方式来处理这些依赖。
		*/
		// ###### 如果一个属性对应的set方法在ignoredDependencyInterfaces接口中被定义了，则该属性不会进行自动注入（是Spring中的自动注入，不是@Autowired）
		//设置了几个忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		// ====== 嵌入式值解析感知器
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

		// ###### 自动注入的支持
		// ====== skip:下面几行就是为特殊的几个 bean 赋值，如果有 bean 依赖了以下几个接口，会注入这边相应的值
		// 设置了几个自动装配的特殊规则
		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// ###### 配置一个可加载所有监听器的组件
		// ====== 为监听器注册早期后置处理器;
		// ====== 如果是 ApplicationListener 的子类，
		// ====== 那么将其添加到 listener 列表中，可以理解成：注册事件监听器
		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		//*****************************智能注册***************************************************
		//  增加对AspectJ的支持，在java中织入分为三种方式，分为编译器织入，类加载器织入，运行期织入，编译器织入是指在java编译器，采用特殊的编译器，将切面织入到java类中，
		//  而类加载期织入则指通过特殊的类加载器，在类字节码加载到JVM时，织入切面，运行期织入则是采用cglib和jdk进行切面的织入
		//  aspectj提供了两种织入方式，第一种是通过特殊编译器，在编译器，将aspectj语言编写的切面类织入到java类中，第二种是类加载期织入，就是下面的load time weaving，此处后续讲
		//  ###### LoadTimeWeaving的支持
		/** ======
			 如果当前BeanFactory包含loadTimeWeaver Bean，说明存在类加载期织入AspectJ
			 则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理
		          从而实现类加载期织入AspectJ的目的。
			 代码织入是3种方式
			 编译期织入（AspectJ）、类加载期（AspectJ）织入和运行期织入(Spring AOP)
		 */
		// ###### Aspectj本身是通过编译期进行代理的，在Spring中就跟LoadTimeWeaver有关
		// 增加对AspectJ的支持
		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// ###### 向BeanFactory中注册Environment、系统配置属性、系统环境的信息
		// ###### Environment本身对于BeanFactory来讲也是一个Bean
		// 注册默认的系统环境bean到一级缓存中
		// ====== 如果没有定义 "environment" 这个 bean，那么 Spring 会 "手动" 注册一个
		// 添加默认的系统环境bean
		// Register default environment beans.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			// ====== 进入
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); // ===>
		}
		// ====== 同上！手动 systemProperties
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			// ====== 进入
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());// ===>
		}

		// ====== 同上！手动 systemEnvironment
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			// ====== 进入
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
		// ====== 断点到这里，可以查看debugger里的beanFactory设置了几个信息（就干了这么点事！）
		// ====== ignoreDependencyInterface , manualSingletonNames ,  registeredSingletons ,  singleObjects
	}

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. The initial definition resources will have been loaded but no
	 * post-processors will have run and no derived bean definitions will have been
	 * registered, and most importantly, no beans will have been instantiated yet.
	 * <p>This template method allows for registering special BeanPostProcessors
	 * etc in certain AbstractApplicationContext subclasses.
	 * @param beanFactory the bean factory used by the application context
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

	}

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	// 实例化并且调用所有已经注册了的beanFactoryPostProcessor,遵循指明的顺序
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值，并且实例化调用执行所有已经注册的beanFactoryPostProcessor
		// 默认情况下，通过getBeanFactoryPostProcessors()来获取已经注册的BFPP，但是默认是空的，那么问题来了，如果你想扩展，怎么进行扩展工作？
		// ###### 执行BeanFactory的后置处理器
		// ====== 此处反射调用了BeanFactory后置处理器，近200 Line
		// ====== 调用顺序一：bean定义注册后置处理器
		// ====== 调用顺序二：bean工厂后置处理器
		// ====== 也会调用getBean---doGetBean---createBean----doCreateBean
		// ###### 重点
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// ===>

		// ###### AOP的支持
		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		// 关于LoadTimeWeaver看这篇文章了解即可，https://www.cnblogs.com/wade-luffy/p/6073702.html
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null &&
				beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

	/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	// 实例化并且注册所有的beanPostProcessor
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// ###### 依然借助PostProcessorRegistrationDelegate完成
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

	/**
	 * Initialize the {@link MessageSource}.
	 * <p>Uses parent's {@code MessageSource} if none defined in this context.
	 * @see #MESSAGE_SOURCE_BEAN_NAME
	 */
	// ====== 国际化，就是加了个bean到factory的single中：MessageSource
	protected void initMessageSource() {
		//  ====== 获取Bean工厂,一般是DefaultListBeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//  ###### 检查是否已经存在MessageSource组件,如果存在,直接赋值
		//  ====== 首先判断是否已有xml文件定义了id为messageSource的bean对象，一般不进这里
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			//  ====== 如果有，则从BeanFactory得到这个bean对象
			//如果在配置中已经配置了 messageSource，那么将 messageSource 提取并记录在this.messageSource中
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			//  ====== 当父类Bean工厂不为空，并且这个bean对象是HierarchicalMessageSource类型
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				//  类型强制转换，转换为HierarchicalMessageSource的类型
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				//  判断父类的messageSource是否为空，如果等于空，则设置父类的messageSource
				// ====== 设置父类MessageSource，此处设置内部的parent messageSource
				if (hms.getParentMessageSource() == null) {
					// ###### 拿父ApplicationContext的messageSource作为this.messageSource的父messageSource
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		// ###### 如果不存在,则会创建一个全新的对象并注册到BeanFactory中
		else {
			//  如果没有xml文件定义信息源对象，新建DelegatingMessageSource类作为messageSource的bean
			// ====== 如果不包含：创建一个新的DelegatingMessageSource（委托/授权消息源）
			// 如果用户并没有定义配置文件，那么使用临时的DelegatingMessageSource以便于作为调用getMessage方法的返回。
			//Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			//  给这个DelegatingMessageSource添加父类消息源
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			//  ====== 将这个messageSource实例注册到Bean工厂中
			// ====== 先去一级缓存去找，没有，直接放到一级缓存。移除二级三级缓存
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

	/**
	 * Initialize the {@link ApplicationEventMulticaster}.
	 * <p>Uses {@link SimpleApplicationEventMulticaster} if none defined in the context.
	 * @see #APPLICATION_EVENT_MULTICASTER_BEAN_NAME
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	// ======= 初始化自定义的事件监听多路广播器
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//  ====== 判断容器中是否存在beanName为applicationEventMulticaster的bd，也就是说自定义的事件监听多路广播器，必须实现ApplicationEventMulticaster接口
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			//  如果有，则从bean工厂得到这个bean对象
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			// ====== 如果没有，则默认采用SimpleApplicationEventMulticaster行事件的广播
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			// ====== 将多播注册到Bean工厂，bean的id是 applicationEventMulticaster，将来可以用这个来获取
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Initialize the {@link LifecycleProcessor}.
	 * <p>Uses {@link DefaultLifecycleProcessor} if none defined in the context.
	 * @since 3.0
	 * @see #LIFECYCLE_PROCESSOR_BEAN_NAME
	 * @see org.springframework.context.support.DefaultLifecycleProcessor
	 */
	//初始化 LifecycleProcessor.如果上下文中没有定义，则使用DefaultLifecycleProcessor
	protected void initLifecycleProcessor() {
		//获取当前上下文的BeanFactory对象
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果beanFactory包含'lifecycleProcessor'的bean，忽略父工厂
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			//让当前上下文引用从beanFactory中获取名为'lifecycleProcessor'的LifecycleProcessor类型的Bean对象
			this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			//如果当前日志级级别是跟踪
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			// 创建一个DefaultLifecycleProcessor实例
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			// 为Bean实例提供所属工厂的回调函数
			defaultProcessor.setBeanFactory(beanFactory);
			// 让当前上下文引用defaultProcessor
			this.lifecycleProcessor = defaultProcessor;
			//将lifecycleProcessor注册到beanFactory中
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Template method which can be overridden to add context-specific refresh work.
	 * Called on initialization of special beans, before instantiation of singletons.
	 * <p>This implementation is empty.
	 * @throws BeansException in case of errors
	 * @see #refresh()
	 */
	//  此方式是模板方法，没有添加任何实现，在springmvc中会有对应的实现
	// ====== 子类实现：默认情况下不执行任何操作。
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
	}

	//  注册监听器
	// ====== 目标：查找所有实现了ApplicationListener，然后进行注册
	/* ======
		1、去集合applicationListeners查找
		2、去bean工厂找到实现ApplicationListener接口的bean
		3、去this.earlyApplicationEvents；准备刷新（启动第一步设置）
	*/
	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	protected void registerListeners() {
		// 遍历应用程序中存在的监听器集合，并将对应的监听器添加到监听器的多路广播器中
		// ###### 把所有的IOC容器中以前缓存好的一组ApplicationListener提取出来,添加到事件广播器中
		// ====== 去集合applicationListeners查找；找到实现ApplicationListener的bean
		// 硬编码方式注册的监听器处理
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			// ====== 增加监听
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 从容器中获取所有实现了ApplicationListener接口的bd的bdName,放入ApplicationListenerBeans集合中
		// ###### 将BeanFactory中定义的所有ApplicationListener类型的组件全部提取出,添加到事件广播器中
		// ====== 在去bean工厂找到实现ApplicationListener接口的bean，debug一下看值！
		// 配置文件注册的监听器处理
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			// ====== 增加监听
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 此处先发布早期的监听器集合
		// ###### 广播早期事件
		// ====== this.earlyApplicationEvents在第一步prepareRefresh()初始化的那个集合
		// ====== 如果有事件被添加进了这集合的话，现在开始处理，将它们广播出去，这里是空的。
		// ###### 添加了事件监听器后，判断是否有earlyApplicationEvents，如果有就使用事件广播器发布earlyApplicationEvents
		// ###### earlyApplicationEvents表示在事件广播器还没生成好之前ApplicationContext所发布的事件
		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null; // ====== 处理完后，清空
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent); // ===> 发布事件，观察者模式
			}
		}
	}

	// ====== 1、设置辅助器：例如：解析器、转换器、类装载器
	// ====== 2、实例化(反射)
	// ====== 3、填充
	// ====== 4、调用前置、后置处理器
	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// ###### 初始化ConversionService,这个ConversionService是用于类型转换的服务接口
		// ###### 它的工作是将配置文件/properties中的数据进行类型转换,得到真正想要的数据类型
		// ====== 1、类型转换器，不重要，往下
		// ###### 如果BeanFactory中存在名字叫conversionService的Bean,则设置为BeanFactory的conversionService属性
		// ###### ConversionService是用来进行类型转化的
		// 为上下文初始化类型转换器
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// ###### 嵌入式值解析器EmbeddedValueResolver的组件注册,它负责解析占位符和表达式
		// ====== 2. 注册解析器
		// ====== 这货用于读取配置文件的内容，就是 ${xxx} 那些符号，解析为properties文件里的值
		// ====== 不重要，继续往下
		// ###### 设置默认的占位符解析器  ${xxx}  ---key
		// 如果beanFactory之前没有注册嵌入值解析器，则注册默认的嵌入值解析器，主要用于注解属性值的解析
		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// ###### 与LoadTimeWeaverAware有关的部分
		// ====== 处理 @EnableLoadTimeWeaving 或  <context:load-time-weaver/> 标记的类
		// ====== 作用：jvm加载时织入某些类，空的，继续
		// 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// ====== 临时类加载器设置为空
		// Stop using the temporary ClassLoader for type matching.
		// 禁止使用临时类加载器进行类型匹配
		beanFactory.setTempClassLoader(null);

		// ###### 冻结配置,此时无论如何获取BeanDefinition的名称集合,
		// ###### 获取到的都是同样的(除非增减新的BeanDefinition)
		// ====== 【冻结配置】冻结所有bean定义，其实就是设置冻结属性变量为true
		// ====== 注册的bean定义不会被修改或进一步后处理，因为马上要创建 Bean 实例对象了
		// 冻结所有的bean定义，说明注册的bean定义将不被修改或任何进一步的处理。
		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// ######【初始化】实例化所有非延迟加载的单实例Bean
		// ====== 备实例化所有的单例bean；
		// ====== 调用bean前置、后置处理器【重点】
		// ###### 实例化非懒加载的单例Bean
		// 初始化剩下的单实例（非惰性的）
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();  // ===>
	}


	/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	//完成刷新
	@SuppressWarnings("deprecation")
	protected void finishRefresh() {
		// ====== 1.清除缓存，其实就是一顿clear
		// Clear context-level resource caches (such as ASM metadata from scanning).
		// 清除上下文级别的资源缓存(如扫描的ASM元数据)
		// 清空在资源加载器中的所有资源缓存
		clearResourceCaches();

		// ====== 2、LifecycleProcessor接口初始化，就是注册了个LifecycleProcessor的bean进去
		// ====== ps：当ApplicationContext启动或停止时，它会通过LifecycleProcessor
		// ====== 来与所有声明的bean的周期做状态更新
		// ====== 而在LifecycleProcessor的使用前首先需要初始化
		// ###### 设置lifecycleProcessor，默认为DefaultLifecycleProcessor
		// 为这个上下文初始化生命周期处理器
		// 初始化LifecycleProcessor.如果上下文中找到'lifecycleProcessor'的LifecycleProcessor Bean对象，
		// 则使用DefaultLifecycleProcessor
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// ====== 3、启动所有实现了LifecycleProcessor接口的bean
		// ====== 挨个调它们的start方法。一般没人用
		// ###### 调用LifecycleBean的start()
		// 首先将刷新传播到生命周期处理器
		// 上下文刷新的通知，例如自动启动的组件
		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// ====== 4、发布一个 ContextRefreshedEvent事件
		// ====== 宣布一下，refresh完成了，如果有需要的listener，那就去处理，一般没人关心
		// 发布最终事件
		// 新建ContextRefreshedEvent事件对象，将其发布到所有监听器。
		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// ====== 5、把当前容器注册到到MBeanServer，jmx会用
		// 参与LiveBeansView MBean，如果是活动的
		// LiveBeansView:Sping用于支持JMX 服务的类
		// 注册当前上下文到LiveBeansView，以支持JMX服务
		// Participate in LiveBeansView MBean, if active.
		if (!NativeDetector.inNativeImage()) {
			LiveBeansView.registerApplicationContext(this);
		}
	}

	/**
	 * Cancel this context's refresh attempt, resetting the {@code active} flag
	 * after an exception got thrown.
	 * @param ex the exception that led to the cancellation
	 */
	protected void cancelRefresh(BeansException ex) {
		this.active.set(false);
	}

	/**
	 * Reset Spring's common reflection metadata caches, in particular the
	 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
	 * and {@link CachedIntrospectionResults} caches.
	 * @since 4.2
	 * @see ReflectionUtils#clearCache()
	 * @see AnnotationUtils#clearCache()
	 * @see ResolvableType#clearCache()
	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
	 */
	// ====== 清除内核缓存；因为我们的对象已经实例化并且注入完毕了
	// ====== 中间过程数据（缓存）就不在需要了
	protected void resetCommonCaches() {
		// ====== 清除之前声明过的方法和列的缓存
		ReflectionUtils.clearCache();
		AnnotationUtils.clearCache();
		// ====== 清除解析类型的缓存、序列化缓存
		ResolvableType.clearCache();
		// ====== 清除所有的类加载器
		CachedIntrospectionResults.clearClassLoader(getClassLoader());
	}


	/**
	 * Register a shutdown hook {@linkplain Thread#getName() named}
	 * {@code SpringContextShutdownHook} with the JVM runtime, closing this
	 * context on JVM shutdown unless it has already been closed at that time.
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * @see Runtime#addShutdownHook
	 * @see ConfigurableApplicationContext#SHUTDOWN_HOOK_THREAD_NAME
	 * @see #close()
	 * @see #doClose()
	 */
	@Override
	public void registerShutdownHook() {
		if (this.shutdownHook == null) {
			// No shutdown hook registered yet.
			this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
				@Override
				public void run() {
					synchronized (startupShutdownMonitor) {
						doClose();
					}
				}
			};
			Runtime.getRuntime().addShutdownHook(this.shutdownHook);
		}
	}

	/**
	 * Callback for destruction of this instance, originally attached
	 * to a {@code DisposableBean} implementation (not anymore in 5.0).
	 * <p>The {@link #close()} method is the native way to shut down
	 * an ApplicationContext, which this method simply delegates to.
	 * @deprecated as of Spring Framework 5.0, in favor of {@link #close()}
	 */
	@Deprecated
	public void destroy() {
		close();
	}

	/**
	 * Close this application context, destroying all beans in its bean factory.
	 * <p>Delegates to {@code doClose()} for the actual closing procedure.
	 * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
	 * @see #doClose()
	 * @see #registerShutdownHook()
	 */
	@Override
	public void close() {
		synchronized (this.startupShutdownMonitor) {
			doClose();
			// If we registered a JVM shutdown hook, we don't need it anymore now:
			// We've already explicitly closed the context.
			if (this.shutdownHook != null) {
				try {
					Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
				}
				catch (IllegalStateException ex) {
					// ignore - VM is already shutting down
				}
			}
		}
	}

	/**
	 * Actually performs context closing: publishes a ContextClosedEvent and
	 * destroys the singletons in the bean factory of this application context.
	 * <p>Called by both {@code close()} and a JVM shutdown hook, if any.
	 * @see org.springframework.context.event.ContextClosedEvent
	 * @see #destroyBeans()
	 * @see #close()
	 * @see #registerShutdownHook()
	 */
	@SuppressWarnings("deprecation")
	protected void doClose() {
		// Check whether an actual close attempt is necessary...
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Closing " + this);
			}

			if (!NativeDetector.inNativeImage()) {
				LiveBeansView.unregisterApplicationContext(this);
			}

			try {
				// Publish shutdown event.
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
			}

			// Stop all Lifecycle beans, to avoid delays during individual destruction.
			if (this.lifecycleProcessor != null) {
				try {
					this.lifecycleProcessor.onClose();
				}
				catch (Throwable ex) {
					logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
				}
			}

			// Destroy all cached singletons in the context's BeanFactory.
			destroyBeans();

			// Close the state of this context itself.
			closeBeanFactory();

			// Let subclasses do some final clean-up if they wish...
			onClose();

			// Reset common introspection caches to avoid class reference leaks.
			resetCommonCaches();

			// Reset local application listeners to pre-refresh state.
			if (this.earlyApplicationListeners != null) {
				this.applicationListeners.clear();
				this.applicationListeners.addAll(this.earlyApplicationListeners);
			}

			// Switch to inactive.
			this.active.set(false);
		}
	}

	/**
	 * Template method for destroying all beans that this context manages.
	 * The default implementation destroy all cached singletons in this context,
	 * invoking {@code DisposableBean.destroy()} and/or the specified
	 * "destroy-method".
	 * <p>Can be overridden to add context-specific bean destruction steps
	 * right before or right after standard singleton destruction,
	 * while the context's BeanFactory is still active.
	 * @see #getBeanFactory()
	 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
	 */
	protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}

	/**
	 * Template method which can be overridden to add context-specific shutdown work.
	 * The default implementation is empty.
	 * <p>Called at the end of {@link #doClose}'s shutdown procedure, after
	 * this context's BeanFactory has been closed. If custom shutdown logic
	 * needs to execute while the BeanFactory is still active, override
	 * the {@link #destroyBeans()} method instead.
	 */
	protected void onClose() {
		// For subclasses: do nothing by default.
	}

	@Override
	public boolean isActive() {
		return this.active.get();
	}

	/**
	 * Assert that this context's BeanFactory is currently active,
	 * throwing an {@link IllegalStateException} if it isn't.
	 * <p>Invoked by all {@link BeanFactory} delegation methods that depend
	 * on an active context, i.e. in particular all bean accessor methods.
	 * <p>The default implementation checks the {@link #isActive() 'active'} status
	 * of this context overall. May be overridden for more specific checks, or for a
	 * no-op if {@link #getBeanFactory()} itself throws an exception in such a case.
	 */
	protected void assertBeanFactoryActive() {
		if (!this.active.get()) {
			if (this.closed.get()) {
				throw new IllegalStateException(getDisplayName() + " has been closed already");
			}
			else {
				throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
			}
		}
	}


	//---------------------------------------------------------------------
	// Implementation of BeanFactory interface
	//---------------------------------------------------------------------

	@Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}

	@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, requiredType);
	}

	@Override
	public Object getBean(String name, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, args);
	}

	@Override
	public <T> T getBean(Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType);
	}

	@Override
	public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType, args);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType);
	}

	@Override
	public boolean containsBean(String name) {
		return getBeanFactory().containsBean(name);
	}

	@Override
	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isSingleton(name);
	}

	@Override
	public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isPrototype(name);
	}

	@Override
	public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isTypeMatch(name, typeToMatch);
	}

	@Override
	public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().isTypeMatch(name, typeToMatch);
	}

	@Override
	@Nullable
	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().getType(name);
	}

	@Override
	@Nullable
	public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
		assertBeanFactoryActive();
		return getBeanFactory().getType(name, allowFactoryBeanInit);
	}

	@Override
	public String[] getAliases(String name) {
		return getBeanFactory().getAliases(name);
	}


	//---------------------------------------------------------------------
	// Implementation of ListableBeanFactory interface
	//---------------------------------------------------------------------

	@Override
	public boolean containsBeanDefinition(String beanName) {
		return getBeanFactory().containsBeanDefinition(beanName);
	}

	@Override
	public int getBeanDefinitionCount() {
		return getBeanFactory().getBeanDefinitionCount();
	}

	@Override
	public String[] getBeanDefinitionNames() {
		return getBeanFactory().getBeanDefinitionNames();
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
	}

	@Override
	public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForType(ResolvableType type) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type);
	}

	@Override
	public String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForType(@Nullable Class<?> type) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type);
	}

	// ====== 参数1：bean的类型
	// ====== 参数2：包括非单例
	// ====== 参数3：所有期望初始化的
	@Override
	public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBeansOfType(type);
	}

	@Override
	public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBeansOfType(type, includeNonSingletons, allowEagerInit);
	}

	@Override
	public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
		assertBeanFactoryActive();
		return getBeanFactory().getBeanNamesForAnnotation(annotationType);
	}

	@Override
	public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
			throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBeansWithAnnotation(annotationType);
	}

	@Override
	@Nullable
	public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
			throws NoSuchBeanDefinitionException {

		assertBeanFactoryActive();
		return getBeanFactory().findAnnotationOnBean(beanName, annotationType);
	}

	@Override
	@Nullable
	public <A extends Annotation> A findAnnotationOnBean(
			String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
			throws NoSuchBeanDefinitionException {

		assertBeanFactoryActive();
		return getBeanFactory().findAnnotationOnBean(beanName, annotationType, allowFactoryBeanInit);
	}


	//---------------------------------------------------------------------
	// Implementation of HierarchicalBeanFactory interface
	//---------------------------------------------------------------------

	@Override
	@Nullable
	public BeanFactory getParentBeanFactory() {
		return getParent();
	}

	@Override
	public boolean containsLocalBean(String name) {
		return getBeanFactory().containsLocalBean(name);
	}

	/**
	 * Return the internal bean factory of the parent context if it implements
	 * ConfigurableApplicationContext; else, return the parent context itself.
	 * @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
	 */
	// ====== 获取内部的父bean工厂
	@Nullable
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
	}


	//---------------------------------------------------------------------
	// Implementation of MessageSource interface
	//---------------------------------------------------------------------

	@Override
	public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
		return getMessageSource().getMessage(code, args, defaultMessage, locale);
	}

	@Override
	public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
		return getMessageSource().getMessage(code, args, locale);
	}

	@Override
	public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
		return getMessageSource().getMessage(resolvable, locale);
	}

	/**
	 * Return the internal MessageSource used by the context.
	 * @return the internal MessageSource (never {@code null})
	 * @throws IllegalStateException if the context has not been initialized yet
	 */
	private MessageSource getMessageSource() throws IllegalStateException {
		if (this.messageSource == null) {
			throw new IllegalStateException("MessageSource not initialized - " +
					"call 'refresh' before accessing messages via the context: " + this);
		}
		return this.messageSource;
	}

	/**
	 * Return the internal message source of the parent context if it is an
	 * AbstractApplicationContext too; else, return the parent context itself.
	 */
	@Nullable
	protected MessageSource getInternalParentMessageSource() {
		return (getParent() instanceof AbstractApplicationContext ?
				((AbstractApplicationContext) getParent()).messageSource : getParent());
	}


	//---------------------------------------------------------------------
	// Implementation of ResourcePatternResolver interface
	//---------------------------------------------------------------------

	@Override
	public Resource[] getResources(String locationPattern) throws IOException {
		return this.resourcePatternResolver.getResources(locationPattern);
	}


	//---------------------------------------------------------------------
	// Implementation of Lifecycle interface
	//---------------------------------------------------------------------

	@Override
	public void start() {
		getLifecycleProcessor().start();
		publishEvent(new ContextStartedEvent(this));
	}

	@Override
	public void stop() {
		getLifecycleProcessor().stop();
		publishEvent(new ContextStoppedEvent(this));
	}

	@Override
	public boolean isRunning() {
		return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
	}


	//---------------------------------------------------------------------
	// Abstract methods that must be implemented by subclasses
	//---------------------------------------------------------------------

	/**
	 * Subclasses must implement this method to perform the actual configuration load.
	 * The method is invoked by {@link #refresh()} before any other initialization work.
	 * <p>A subclass will either create a new bean factory and hold a reference to it,
	 * or return a single BeanFactory instance that it holds. In the latter case, it will
	 * usually throw an IllegalStateException if refreshing the context more than once.
	 * @throws BeansException if initialization of the bean factory failed
	 * @throws IllegalStateException if already initialized and multiple refresh
	 * attempts are not supported
	 */
	// ====== 抽象方法由子类实现AbstractRefreshableApplicationContext
	protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

	/**
	 * Subclasses must implement this method to release their internal bean factory.
	 * This method gets invoked by {@link #close()} after all other shutdown work.
	 * <p>Should never throw an exception but rather log shutdown failures.
	 */
	protected abstract void closeBeanFactory();

	/**
	 * Subclasses must return their internal bean factory here. They should implement the
	 * lookup efficiently, so that it can be called repeatedly without a performance penalty.
	 * <p>Note: Subclasses should check whether the context is still active before
	 * returning the internal bean factory. The internal factory should generally be
	 * considered unavailable once the context has been closed.
	 * @return this application context's internal bean factory (never {@code null})
	 * @throws IllegalStateException if the context does not hold an internal bean factory yet
	 * (usually if {@link #refresh()} has never been called) or if the context has been
	 * closed already
	 * @see #refreshBeanFactory()
	 * @see #closeBeanFactory()
	 */
	@Override
	public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;


	/**
	 * Return information about this context.
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder(getDisplayName());
		sb.append(", started on ").append(new Date(getStartupDate()));
		ApplicationContext parent = getParent();
		if (parent != null) {
			sb.append(", parent: ").append(parent.getDisplayName());
		}
		return sb.toString();
	}

}
